

package cn.shengchao.examstart.user.ohs.local.appservices;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.shengchao.base.constant.CacheConstants;
import cn.shengchao.examstar.rpc.uddsys.bi.PlatformUserArchBI;
import cn.shengchao.examstar.rpc.uddsys.dto.PlatformUserInfoDto;
import cn.shengchao.examstart.user.acl.adapters.message.MemberStudent;
import org.apache.dubbo.config.annotation.DubboReference;
import top.continew.admin.common.model.dto.LoginUser;
import cn.shengchao.examstart.user.acl.ports.repositories.IUserRepository;
import cn.shengchao.examstart.user.domain.entity.UserPreference;
import cn.shengchao.examstart.user.domain.vlobj.SocialSourceEnum;
import cn.shengchao.examstart.user.domain.entity.User;
import cn.shengchao.examstart.user.domain.entity.UserSocial;
import cn.shengchao.examstart.user.ohs.local.messages.SaveUserPreference;
import cn.shengchao.examstart.user.ohs.local.messages.UserInfoDto;
import cn.shengchao.examstart.user.ohs.local.messages.UserPreferenceDto;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.continew.admin.common.model.dto.RoleDTO;
import top.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.core.validation.CheckUtils;
import top.continew.starter.core.validation.ValidationUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserAppService {

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private IUserRepository iUserRepository;

    @DubboReference
    private PlatformUserArchBI platformUserArchBI;

    /**
     * 手机号登录appid做用户
     *
     * @param phone
     * @return
     */
    public LoginUser simplePhoneWxLogin(String phone) {
        log.info("手机号登录appid做用户,appid:{}", phone);
        List<User> userList = iUserRepository.selectByPhone(phone);
        if (CollUtil.isNotEmpty(userList)) {
            User user = userList.getFirst();
            LoginUser loginUser = new LoginUser();
            loginUser.setOpenId("openId");
            loginUser.setUsername(user.getUsername());
            loginUser.setId(user.getId());
            loginUser.setNickname(user.getName());
            loginUser.setAvatar(user.getAvatar());
            loginUser.setPermissions(new HashSet<>());
            return loginUser;
        } else {
            PlatformUserInfoDto platformUserInfoDto = new PlatformUserInfoDto();
            platformUserInfoDto.setPhone(phone);
            platformUserInfoDto.setNickname(DesensitizedUtil.mobilePhone(phone));
            platformUserInfoDto.setGender(0);
            PlatformUserInfoDto platformUserInfoDto1 = platformUserArchBI.createPlatformUser(platformUserInfoDto);
            if (platformUserInfoDto1 == null || platformUserInfoDto1.getId() == null) {
                throw new RuntimeException("创建用户失败");
            }
            User user = iUserRepository.of(platformUserInfoDto1.getId());
            LoginUser loginUser = new LoginUser();
            loginUser.setOpenId("openId");
            loginUser.setUsername(user.getUsername());
            loginUser.setId(user.getId());
            loginUser.setNickname(user.getName());
            loginUser.setAvatar(user.getAvatar());
            loginUser.setPermissions(new HashSet<>());
            return loginUser;
        }
    }

    /**
     * 模拟登录appid做用户
     *
     * @param appid
     * @param jsCode
     * @return
     */
    public LoginUser simpleWxLogin(String appid, String jsCode) {
        log.info("模拟微信登录,appid:{},jsCode:{}", appid, jsCode);
        User user = iUserRepository.of(Long.valueOf(appid));
        LoginUser loginUser = new LoginUser();
        loginUser.setOpenId("openId");
        loginUser.setUsername(user.getUsername());
        loginUser.setId(user.getId());
        loginUser.setNickname(user.getName());
        loginUser.setAvatar(user.getAvatar());
//        loginUser.setRoles(user.getRoleId().stream().map(role -> {
//            RoleDTO roleDTO = new RoleDTO();
//            roleDTO.setCode(String.valueOf(role));
//            roleDTO.setId(role);
//            return roleDTO;
//        }).collect(Collectors.toSet()));

        loginUser.setPermissions(new HashSet<>());
        return loginUser;
    }

    public LoginUser wxLogin(String appid, String jsCode) throws WxErrorException {
        log.info("微信登录,appid:{},jsCode:{}", appid, jsCode);
        wxMaService.switchoverTo(appid);
        WxMaJscode2SessionResult wxMaJscode2SessionResult = wxMaService.getUserService().getSessionInfo(jsCode);
        String openId = wxMaJscode2SessionResult.getOpenid();
        String unionId = wxMaJscode2SessionResult.getUnionid();
        log.info("appid:{},获取到用户微信openid:{},unionId:{}", appid, openId, unionId);
        Optional<User> userOptional = iUserRepository.getUserBySocial(appid, openId, unionId);
        User user = userOptional.orElseGet(User::new);
        if (user.getId() == null || user.getPhone() == null) {
            log.info("未获取到用户信息,用户未绑定手机号,appid:{},openId:{},创建用户微信登录信息", appid, openId);
            user.setUserSocial(Lists.newArrayList(UserSocial.of(SocialSourceEnum.WX, appid, openId, unionId)));
            iUserRepository.saveWxUser(user);
            LoginUser loginUser = new LoginUser();
            loginUser.setOpenId(openId);
            return loginUser;
        }
        LoginUser loginUser = new LoginUser();
        loginUser.setOpenId(openId);
        loginUser.setUsername(user.getUsername());
        loginUser.setId(user.getId());
        loginUser.setNickname(user.getName());
        loginUser.setAvatar(user.getAvatar());
        loginUser.setRoles(user.getRoleId().stream().map(role -> {
            RoleDTO roleDTO = new RoleDTO();
            roleDTO.setCode(String.valueOf(role));
            roleDTO.setId(role);
            return roleDTO;
        }).collect(Collectors.toSet()));

        loginUser.setPermissions(new HashSet<>());
        return loginUser;
    }

    public LoginUser phoneLogin(String appid, String phone, String code) {
        String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + phone;
        String captcha = RedisUtils.get(captchaKey);
        ValidationUtils.throwIfBlank(captcha, "验证码已失效");
        ValidationUtils.throwIfNotEqualIgnoreCase(code, captcha, "验证码不正确");
        RedisUtils.delete(captchaKey);
        return simplePhoneWxLogin(phone);
    }

    public LoginUser bindPhone(String appid, String code, String openId) throws WxErrorException {
        WxMaPhoneNumberInfo wxMaPhoneNumberInfo = wxMaService.getUserService().getPhoneNoInfo(code);
        if (wxMaPhoneNumberInfo != null) {
            String phoneNumber = wxMaPhoneNumberInfo.getPhoneNumber();
            log.info("绑定手机号,appid:{},openId:{},phoneNumber:{}", appid, openId, phoneNumber);
            User user = iUserRepository.getUserBySocial(appid, openId, null).orElseThrow(() -> new RuntimeException("用户不存在"));
            if (StrUtil.isEmpty(user.getName())) {
                user.setName(DesensitizedUtil.mobilePhone(phoneNumber));
                user.setPassword(RandomUtil.randomString(16));
                user.setUsername(phoneNumber);
                user.setPhone(phoneNumber);
            }
            user = iUserRepository.saveWxUser(user);
            LoginUser loginUser = new LoginUser();
            loginUser.setId(user.getId());
            loginUser.setUsername(user.getName());
            loginUser.setOpenId(openId);
            loginUser.setRoleCodes(user.getRoleId().stream().map(String::valueOf).collect(Collectors.toSet()));
            loginUser.setRoles(new HashSet<>());
            loginUser.setPermissions(new HashSet<>());
            loginUser.setNickname(user.getName());
            loginUser.setAvatar(user.getAvatar());
            return loginUser;
        }
        CheckUtils.throwIf(null, "绑定手机号失败！");
        return null;
    }

    public void setUserInfo(UserInfoDto userInfoReq, Long userId) {
        User user = iUserRepository.of(userId);
        if (StrUtil.isNotEmpty(userInfoReq.getAvatarUrl())) {
            log.info("用户:{}更新头像:{}", user.getUsername(), userInfoReq.getAvatarUrl());
            user.setAvatar(userInfoReq.getAvatarUrl());
        }
        if (StrUtil.isNotEmpty(userInfoReq.getNickName())) {
            log.info("用户:{}更新昵称:{}", user.getUsername(), userInfoReq.getNickName());
            user.setName(userInfoReq.getNickName());
        }
        iUserRepository.saveWxUser(user);
    }

    public UserPreferenceDto getUserPreference(Long userId) {
        UserPreference userPreference = iUserRepository.getUserPreference(userId);
        log.info("获取用户偏好：{}", userId);
        UserPreferenceDto userPreferenceDto = new UserPreferenceDto();
        if (userPreference != null) {
            userPreferenceDto.setName(userPreference.getName());
            userPreferenceDto.setValue(userPreference.getValue());
        }
        return userPreferenceDto;
    }

    public void saveUserPreference(SaveUserPreference saveUserPreference, Long userId) {
        iUserRepository.saveUserPreference(saveUserPreference, userId);
        log.info("更新用户偏好成功：{}", userId);

    }

    public UserInfoDto getUserInfo(Long userId) {
        User user = iUserRepository.of(userId);
        log.info("获取用户信息:{}", user.getId());
        return UserInfoDto.of(user.getName(), user.getAvatar());
    }

    public List<MemberStudent> selectMemberStudent(Long userId, String searchValue) {
        return iUserRepository.selectMemberStudent(userId, searchValue);
    }


}
